<template>
  <base-scroll class="scroll-wrapper" ref="scroll"
    :options="scrollOptions"
    :data="list">
    <div class="s-al">
      <!-- fixed: 使用 index 保证 key 唯一 -->
      <component :is="componentItem"
        v-for="(item, index) of list" :key="item.id + index"
        :[type]=item
        @play-song="playSong"/>
      <div class="pullup-tips" v-show="hasMore">
        <base-loading-spinner v-show="loading"
          width="30px"
          height="30px"
          color="rgb(238, 10, 36)"
          itemWidth="8%"/>
      </div>
    </div>
  </base-scroll>
</template>

<script>
import SongItem from '@/components/SongItem'
import PlaylistItem from './SearchPlaylistItem'
import ArtistItem from './SearchArtistItem'
import AlbumItem from './SearchAlbumItem'
import { upper, upperFirst } from '@/utils'

export default {
  name: 'search-album',
  components: {
    SongItem,
    PlaylistItem,
    ArtistItem,
    AlbumItem
  },
  props: {
    type: {
      type: String,
      validate: (val) => ['song', 'playlist', 'artist', 'album'].includes(val)
    },
    keywords: { type: String, require: true }
  },
  data () {
    return {
      loading: true, // 是否正在加载
      count: null, // 可以加载的总数
      list: [], // 当前加载的列表
      scrollOptions: {
        scrollX: false,
        scrollY: true,
        click: true,
        pullUpLoad: {
          threshold: 0
        }
      }
    }
  },
  computed: {
    componentItem () {
      return `${upperFirst(this.type)}Item`
    },
    scroll () {
      return this.$refs.scroll
    },
    hasMore () {
      // 保证初值为 true，带请求后更新 this.count 再改变值
      return this.count === null ? true : this.list.length < this.count
    }
  },
  mounted () {
    this.$nextTick(async _ => {
      // 注册 pullingUp 事件
      this.scroll.getScroll().on('pullingUp', this.pullingUpHandler)
      await this.initData()
    })
  },
  methods: {
    initData () {
      return new Promise(resolve => {
        setTimeout(async () => {
          const { data } = await this.$api.getSearch({
            type: upper(this.type),
            limit: 20,
            offset: this.list.length,
            keywords: this.keywords
          })
          this.loading = false
          console.log('成功获取数据...')
          // 冻结属性，提高性能
          const appendList = data.result[`${this.type}s`].map(v => Object.freeze(v))
          this.list = this.list.concat(appendList)
          this.count = data.result[`${this.type}Count`]
          resolve()
        }, 1000)
      })
    },
    async pullingUpHandler () {
      // 没有更多数据可加载时
      console.log('trigger pullingup...')
      if (!this.hasMore) return
      this.loading = true
      await this.initData()
      // 告知本次 pullingUp 事件完成
      this.scroll.getScroll().finishPullUp()
      this.scroll.refresh()
      this.loading = false
    },
    playSong (song) {
      this.$store.dispatch('player/changeSong', { song })
    }
  },
  watch: {
    keywords () {
      this.loading = true
      this.count = 0
      this.list.length = 0
      this.initData().then()
    }
  }
}
</script>

<style lang="scss">
.scroll-wrapper {
  overflow: hidden;
  height: calc(100vh - 1.44rem);
  height: calc(var(--vh, 1vh) * 100 - 1.44rem);
}

.pullup-tips {
  box-sizing: border-box;
  height: .5rem;
  padding: .1rem 0;
  /* background-color: #ccc; */
}
</style>
